import axios, { AxiosResponse, AxiosRequestConfig, AxiosInstance } from "axios";
import ekMessage from "@/utils/message";
import { storage } from "@/utils/storage";
import { setToken, getToken, getRefreshToken, logoutClear } from "@/utils/sys";
import router from "@/router";

const baseurl = "./";
const config = {
  baseURL: "/",
  timeout: 40000,
  withCredentials: true, // 是否携带cookie
  // headers: {
  //   "Content-Type": "application/json",
  // },
};

//是否有请求正在刷新token
let isRefreshing = false;
// 重试请求队列 每一项都是一个待执行待函数
let requests = [];

// 创建对象
const http = axios.create(config);

// 请求拦截器
http.interceptors.request.use(
  (config) => {
    // 支持http/https
    let reg = /(http|https):\/\/([\w.]+\/?)\S*/gi;
    if (!config.url.match(reg)) {
      config.url = baseurl + config.url;
    }
    // 设置token
    config.headers["Authorization"] = getToken();
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
http.interceptors.response.use(
  (response) => {
    console.log(response, "responseresponseresponseresponse");
      // 原请求配置
    const originalRequest = response.config;
    // execl 下载
    if (
      response.headers["content-type"] ==
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    ) {
      return Promise.resolve(response.data);
    } else {
      console.log(response, "responseresponse");
      if (response.data.status === "success") {
        // 成功
        return Promise.resolve(response.data);
      } else if (response.data.status === "refresh_token") {
        // 刷新token 逻辑
        let refreshToken = getRefreshToken(storage.events.refreshToken);
        if (refreshToken) {
          return doRefreshToken(originalRequest, refreshToken);
        } else {
          // 退出登陆
          doLogout();
        }
      } else {
        // 失败，不同编码下的处理
        codeHandle(response.data.code, response.data.message);
        return Promise.reject();
      }
    }
  },
  (error) => {
    // 错误处理
    errorHandle(error);
    return Promise.reject(error);
  }
);

// 失败逻辑处理
function codeHandle(code, message) {
  ekMessage.error(message);
}
// 错误处理
function errorHandle(error) {

  if (error.response) {
    switch (error.response.status) {
      case 401:
        // 退出登陆
        doLogout();
        break;
      case 403:
        // 没有权限
        ekMessage.error("暂无权限");
        break;
      case 404:
        ekMessage.error("接口不存在");
        break;
      default:
        ekMessage.error(error.response.data.message);
      // 其他错误
    }
  } else {
    // 网络错误
    if (error.message.search("Network Error") > -1) {
    }
    // 超时
    if (error.message.search("timeout") > -1) {
    }
  }
}

/*把过期请求添加在数组中*/
const addRequest = (request) => {
  requests.push(request);
}
/*调用过期请求*/
const retryRequest = (token) => {
  requests.forEach(request => request(token))
  requests = []
}
// 刷新token 逻辑
function doRefreshToken(originalRequest, refreshToken) {
  // 是否刷新中
  if (!isRefreshing) {
    // 没有则请求刷新token
    isRefreshing = true;
    return http
      .post("/admin/login/refreshToken", {
        refreshToken: refreshToken,
      })
      .then((res) => {
        if (res.status === "success") {
          // 重新设置token
          setToken(res.data.token);
          // 发起队列和原请求
          originalRequest.headers["Authorization"] = res.data.token;
          retryRequest(res.data.token);
          return http(originalRequest);
        }
      })
      .finally(() => {
        isRefreshing = false;
      });
  } else {
    // 正在刷新token，加入队列中，将返回一个未执行resolve的promise
    return new Promise((resolve) => {
      // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
      addRequest((token) => {
        originalRequest.headers.Authorization = token;
        resolve(http(originalRequest));
      });
    });
  }
}
// 退出的一些操作
function doLogout() {
  // 调用登出接口
  // 清除本地数据
  doClear();
  // 跳转登陆页
  goLogin();
}
// 清除的一些操作
function doClear() {
  logoutClear();
  // 跳转登陆页
}
function goLogin() {
  router.push({ path: "/login" });
}
export default http;
